#!/usr/bin/perl
use File::Path;

#Obtengo los parametros
($comando, $tipo, $mensaje, $nombreLog) = @ARGV;

#Obtengo la dirección del archivo de log
#HIPOTESIS: el path me viene con la "/" al final
$dir = getEnvVariable("LOGDIR");
if(!$dir){
  $dir = getEnvVariable("GRUPO");
  if(!$dir){
#   En el caso que no este nada inicializado, se deja el log en confdir/,
#   Probablemente sea porque fue llamado desde InstalarT
    $dir = "confdir/"
  } else {
    $dir.= "logdir/";
  }
}

#Defino la dirección donde se loguearan los errores producidos en el log
$logPropio = "../tmp/LoguearT.log";

#Si el directorio no existe, lo crea
if(!(-d $dir)){
  mkpath($dir,{error => \my $err});
  if(@$err){
    $NO_PATH = getEnvVariable("NO_PATH");
    $mensaje_log = $NO_PATH;
    $mensaje_log =~ s/&1/$dir/g;
    grabarErrorLog($logPropio,"$mensaje_log", "mkpath");
    exit(1);
  }
}

#Nombre del archivo a escribir
$dir.= "$nombreLog";

#obtengo la extension del archivo de log
$ext = getEnvVariable("LOGEXT");
if(!$ext){
  $ext = ".log";
}
$dir.= $ext;

#verificar el tamaño el log y reducirlo si es necesario
$logExcedido = checkTamLog($dir);

if(!open(LOG,">>$dir")){
  $NO_OPEN = getEnvVariable("NO_OPEN");
  $mensaje_log = $NO_OPEN;
  $mensaje_log =~ s/&1/append/g;
  $mensaje_log =~ s/&2/$dir/g;
  grabarErrorLog($logPropio,"$mensaje_log", "open");
  exit(1);
}

#Obtengo el tiempo local
($sec,$min,$hour,$mday,$mon,$year) = localtime(time);

#Obtengo el usuario
$user = getlogin();

#Remuevo caracteres extraños
$mensaje = transformMessage($mensaje);

#Imprimo el mensaje al log
printf LOG "%4d%02d%02d %02d:%02d:%02d-%s-%s-%s-%s\n",
       $year+1900,$mon+1,$mday,$hour,$min,$sec,$user,$comando,$tipo,$mensaje;

#Imprimo el mensaje de "log excedido" cuando corresponda
if( $logExcedido != 0 ){
  $LOG_EXC = getEnvVariable("LOG_EXC");
  printf LOG "%4d%02d%02d %02d:%02d:%02d-%s-%s-%s-%s\n",
         $year+1900,$mon+1,$mday,$hour,$min,$sec,$user,"LoguearT","I","$LOG_EXC";
}

close(LOG);
exit(0);

#----------------------------------------------------------------------------------------------------------------------
#SUBRUTINAS
#----------------------------------------------------------------------------------------------------------------------
#Subrutnina que recibe el nombre de una variable de ambiente del bash y devuelve su valor 
sub getEnvVariable{
  my $envVar = `env | grep $_[0]= | sed s/^$_[0]=//`;
  chomp($envVar);
  return $envVar;
}

#Subrutnina que checkea que el log a escribir no supere el tamaño maximo
#Si se supera el tamaño maximo, se eliminan el 50% de los mensajes mas antiguos
sub checkTamLog{
  my $file = $_[0];
  my $maxSize = getEnvVariable("LOGSIZE");
  if(!$maxSize){
    $maxSize = "102400"; #100 Kb 
  } else {
#   Transformo de Kb a Bytes
    $maxSize = $maxSize * 1024;
  }

  my $fileSize = -s "$file";

  if($fileSize >= $maxSize){
    $lines = `wc -l "$file"`;
    $lines =~ s/ .*\n$//;
    
    #Leo todo el archivo a un array invertido en memoria
    if(open(FH,"$file")){
      @backLines = reverse <FH>;
      close(FH);

      #Copio el 50% de los mensajes y hago las verificaciones
      for($i = 0 ; $i < $lines / 2 ; $i++ ){
        unshift(@newLog,@backLines[$i]);
      }
      if(!open(FH,">$file")){
 	$NO_OPEN = getEnvVariable("NO_OPEN");
	$mensaje_log = $NO_OPEN;
	$mensaje_log =~ s/&1/write/g;
	$mensaje_log =~ s/&2/$file/g;
        grabarErrorLog($logPropio,"$mensaje_log", "checkTamLog");
        return 0;
      } else {
        foreach(@newLog){
          print FH $_;
        }    
      }
      close(FH);
      return 1;
    } else {
 	$NO_OPEN = getEnvVariable("NO_OPEN");
	$mensaje_log = $NO_OPEN;
	$mensaje_log =~ s/&1/read/g;
	$mensaje_log =~ s/&2/$file/g;
        grabarErrorLog($logPropio,"$mensaje_log", "checkTamLog");
      return 0;
    }
  }
  return 0;
}

#Subrutina que elimina caracteres extraños y dobles espacios
#Se utilizan los POSIX character sets
sub transformMessage{
  #Saca los espacios en blanco multiples(incluye tabs)
  $_[0] =~ s/[[:blank:]]+/ /g;

  #Saca todo lo que no sea "Printable and visible characters"
  $_[0] =~ s/[^[:graph:] ñÑ]+//g;

  #Escapea los '-' por ser el separador de archivo
  $_[0] =~ s/-/\\-/g;

  #Corta el mensaje a los 140 caracteres
  $longitud = length($_[0]);

  if($longitud > 140){
    $_[0] = substr($_[0],0,140);
}
  return $_[0];
}

#Graba en el Log propio los errores producidos durante el proceso de Logueo
sub grabarErrorLog{
  if(open(LOGP,">>$_[0]")){
    #Obtengo el tiempo local
    ($sec,$min,$hour,$mday,$mon,$year) = localtime(time);

    #Obtengo el usuario
    $user = getlogin();

    #Remuevo caracteres extraños
    $_[1] = transformMessage($_[1]);

    #Imprimo el mensaje al log
    printf LOGP "%4d%02d%02d %02d:%02d:%02d-%s-%s-%s-%s\n",
    $year+1900,$mon+1,$mday,$hour,$min,$sec,$user,$_[2],"E",$_[1];
  }
}
